package miao

import (
	"bufio"
	"bytes"
	"encoding/binary"
	"encoding/json"
)

// 对TCP消息进行编解码，解决粘包问题

// Encode 将消息编码.miao
func Encode(msg any) ([]byte, error) {
	data, err := json.Marshal(msg)
	if err != nil {
		return nil, err
	}
	// 读取消息的长度，转换成int32类型（占4个字节）
	length := int32(len(data))
	pkg := new(bytes.Buffer)
	// 写入消息头
	err = binary.Write(pkg, binary.LittleEndian, length)
	if err != nil {
		return nil, err
	}
	// 写入消息实体
	err = binary.Write(pkg, binary.LittleEndian, data)
	if err != nil {
		return nil, err
	}
	return pkg.Bytes(), nil
}

// Decode 解码消息.miao
func Decode(reader *bufio.Reader) ([]byte, error) {
	// 读取消息的长度
	lengthByte, err := reader.Peek(4) // 读取前4个字节的数据
	if err != nil {
		return nil, err
	}
	lengthBuff := bytes.NewBuffer(lengthByte)
	var length int32
	err = binary.Read(lengthBuff, binary.LittleEndian, &length)
	if err != nil {
		return nil, err
	}
	// Buffered返回缓冲中现有的可读取的字节数。
	if int32(reader.Buffered()) < length+4 {
		pack := make([]byte, length+4)
		var n int
		n, err = reader.Read(pack)
		if err != nil {
			return nil, err
		}
		return pack[:n], nil
	}
	// 读取真正的消息数据
	pack := make([]byte, int(4+length))
	_, err = reader.Read(pack)
	if err != nil {
		return nil, err
	}
	return pack[4:], nil
}
